function escribir(mensaje) {
	$("#info").append("<p>" + mensaje + "</p>");
	$("#info").scrollTop($("#info").attr('scrollHeight'));
}

function desactivar() {
	$("#colabora").val("Parar");
	$(".mas").attr('disabled', true);
	$(".menos").attr('disabled', true);
	escribir("- Iniciando el cálculo de " + cantidad + " dígitos...");
	aux = cantidad;
}

function activar() {
	$(".mas").removeAttr('disabled');
	$(".menos").removeAttr('disabled');
	$("#colabora").val("Calcular");
	$("#colabora").removeAttr('disabled');
	escribir("- Parado");
	cantidad = aux;
}

function calcular() {
	var timestamp = new Date().getTime();
	$.get('/@api', {request: 'seed', timestamp: timestamp}, function(seed) {
		escribir("- Semilla: " + seed);
		timeout = setTimeout(function() {generateDigit(parseInt(seed))}, 10);
	});
}

function guardar(semilla, digito) {
	escribir("- Dígito calculado: " + digito);
	cantidad -= 1;
	$.post('/@api', {seed: semilla, hex: digito});
	if (cantidad === 0) activar();
	else calcular();
}

function parar() {
	escribir("- Parando...");
	clearTimeout(timeout);
	cantidad = 1;
}

/*********************************************************************
 * Extraído de http://www.csc.liv.ac.uk/~acollins/pi 
 *********************************************************************/
function modPow(B, E, M)
{
	var result = 1;
	while (E > 0)
	{
		if ((E & 1) === 1)
			result = (result * B) % M;
		E >>= 1;
		B = (B * B) % M;
	}
	return result % M;
}

function S (j, d)
{
	var sumLeft = 0;
	/*
	 * First Summation
	 */
	for (var k = 0; k <= d; k++) {
		var r = 8 * k + j; // 8k + j
		sumLeft += modPow(16, d - k, r) / r;
		sumLeft = sumLeft % 1.0;
	}
	/*
	 * Second Summation Used for generating the trailing digits The more
	 * cycles performed, the more accurate the precision
	 */
	var sumRight = 0;
	var k = d + 1;

	while (true) // To infinity... and beyond!
	{
		var sumConverge = sumRight + Math.pow(16, d - k) / (8 * k + j);
		// Iterate until SumRight no longer changes
		if (sumRight === sumConverge)
			break;
		else
			sumRight = sumConverge;
		k++;
	}
	return sumLeft + sumRight;
}

function generateDigit(d)
{
	var Sx = 4 * S(1, d);
	Sx -= 2 * S(4, d);
	Sx -= S(5, d);
	Sx -= S(6, d);

	if (Sx > 0)
		Sx -= parseInt(Sx);

	if (Sx < 0)
		Sx += (1 + parseInt(-Sx));

	Sx *= Math.pow(16, 14);
	var hex = Sx.toString(16);

	while (hex.length < 14)
		hex = "0" + hex;

	guardar(d, hex);
}
/*********************************************************************
 *********************************************************************/